﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RQX.Common.Core.Extension;
using RQX.Common.Core.Hardware.BaseCollection;
using RQX.Common.Core.Hardware.Net;
using RQX.Common.Core.Logger;

namespace RQX.DataCollection.Plugs.Mindray_T5
{
    public class T5 : AbstractTcpClientCollection
    {
        public override string IP => "";
        public override int Port => 4601;
        public T5() { }
        public T5(StructureModel<TcpSocketClient> structureModel) : base(structureModel) { }

        protected override Dictionary<string, string> AnalysisData(string ReceivedString)
        {
            var dic = new Dictionary<string, string>();
            //Console.WriteLine(ReceivedString);
            string[] splitStrings = ReceivedString.Split(new string[] { "\r" }, StringSplitOptions.RemoveEmptyEntries);
            splitStrings.ForEach(row =>
            {
                var detail = ResolveOBX(row.Trim());
                if (detail.Key.IsNotNull())
                {
                    dic.Add(detail.Key, detail.Value);
                }
            });
            return dic;
        }

        
    
        protected override void CircleSend()
        {
            while (true)
            {
                string strNow = DateTime.Now.ToString("yyyyMMddHHmmss");
                string msh = @"MSH|^~\&|||||||QRY^R02|1203|P|2.3.1" + (char)13;
                string qrd = @"QRD|" + strNow + "|R|I|Q839572|||||RES" + (char)13;
                string qrf = @"QRF|MON||||0&0^1^1^1^101&102&103&104" + (char)13;
                string sendData = msh + qrd + qrf;

                byte[] bytContent = Encoding.GetEncoding("GB2312").GetBytes(sendData);

                byte[] bytSend = new byte[bytContent.Length + 3];
                bytSend[0] = 0x0B;
                Array.Copy(bytContent, 0, bytSend, 1, bytContent.Length);

                bytSend[bytSend.Length - 2] = 0x1C;
                bytSend[bytSend.Length - 1] = 0x0D;

                Send(bytSend);
                Thread.Sleep(5000);
            }
        }

        protected override void Connect(StepType stepNum) => Task.Run(() => CircleSend());

        protected override string CutToOneMsg(StringBuilder sb) => sb.ToString();

        protected override void RecvData(byte[] buffer)
        {
            _lastRecvTime = DateTime.Now;
            var recvStr = buffer.ToUTF8();
            WriteRecvLogMethod(recvStr);

            var list = recvStr.Split(new string[]{ "\u001C" },StringSplitOptions.RemoveEmptyEntries);

            list.ForEach(msg =>
            {
                string[] splitStrings = msg.Split(new string[] { "\r" }, StringSplitOptions.RemoveEmptyEntries);
                if (splitStrings == null || splitStrings.Length == 0 || !splitStrings[0].StartsWith($"\v{MSH}")) return;

                string[] mshData = splitStrings[0].Split(new string[] { "|" }, StringSplitOptions.None);
                if (mshData.Length < 9 || !mshData[8].Equals("ORU^R01")) return;

                string messageID = mshData[9];
                if (messageID.IsNullOrEmpty()) return;

                switch (messageID)
                {
                    case TCP_MESSAGE_CONTROL_ID: 
                        SendAnwer();
                        break;
                    case PHYSIOLOGICAL_PARAM_MESSAGE_CONTROL_ID:
                    case NIBP_MESSAGE_CONTROL_ID:
                        var data = AnalysisData(msg);
                        WriteAnalysisLogMethod(data);
                        DealDataHandler?.Invoke(data);
                        break;
                }
            });
        }

        #region private

        private void SendAnwer()
        {
            string strData = @"MSH|^~\&|||||||ORU^R01|106|P|2.3.1|";
            byte[] bytContent = Encoding.GetEncoding("GB2312").GetBytes(strData);
            byte[] bytSend = new byte[bytContent.Length + 3];
            bytSend[0] = 0x0B;
            Array.Copy(bytContent, 0, bytSend, 1, bytContent.Length);
            bytSend[bytSend.Length - 2] = 0x1C;
            bytSend[bytSend.Length - 1] = 0x0D;
            Send(bytSend);
        }
        private KeyValuePair<string, string> ResolveOBX(string RowData)
        {
            var detail = new KeyValuePair<string, string>(null, null);
            if (RowData.IsNullOrEmpty() || !RowData.StartsWith(OBX)) return detail;

            string[] obxData = RowData.Split(new string[] { "|" }, StringSplitOptions.None);
            if (obxData.IsNull() || obxData.Length < 6) return detail;

            var value = GetValue(obxData[5]);
            if (value.Contains(INVALID_VALUE)) return detail;

            var key = GetValue(obxData[3]);
            detail = new KeyValuePair<string, string>(key, value);
            return detail;
        }

        private string GetValue(string str)
        {
            switch (str)
            {
                case "170^Sys":return "NIBP_SYS";//无创
                case "171^Dia": return "NIBP_DIA";//无创
                case "500^Sys": return "IBP1_DIA";//有创
                case "502^Dia": return "IBP1_DIA";//有创
            }
            var value = str.Trim();
            var index = value.IndexOf('^');
            return index == -1 ? value : value.Substring(index+1);
        }

        protected override StepType CheckRecvMsgType(string lineStr)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region 常量
        private const string OBX = "OBX";

        private const string MSH = "MSH";

        /// <summary>
        /// TCP维持消息
        /// </summary>
        private const string TCP_MESSAGE_CONTROL_ID = "106";

        /// <summary>
        /// 周期性生理参数消息
        /// </summary>
        private const string PHYSIOLOGICAL_PARAM_MESSAGE_CONTROL_ID = "204";

        /// <summary>
        /// NIBP生理参数消息（非周期性生理参数）
        /// </summary>
        private const string NIBP_MESSAGE_CONTROL_ID = "503";

        /// <summary>
        /// 生理报警消息
        /// </summary>
        private const string PHYSIOLOGICAL_ALARM_MESSAGE_CONTROL_ID = "54";

        /// <summary>
        /// 技术报警消息
        /// </summary>
        private const string TECHNICAL_ALARM_MESSAGE_CONTROL_ID = "56";

        /// <summary>
        /// 无效的value值
        /// </summary>
        private const string INVALID_VALUE = "-100";

        
        #endregion
    }
}
